*******************************************************************************
* Menus
*
* (C)  Copyright Apple Computer, Inc. 1988
* All rights reserved.
*
* by Jim Mensch
* 7/11/88
*
* Sample Application that demonstrates the use of many menu manager
* calls. It Shows how to add or remove whole menus or menu items, and how to
* manipulate existing items.
* It also demonstrates how to create a custom menu and handle user 
* interactions with it. The custom menu can be removed from this program and 
* incorporated inside your own applications. The custom menu is a color menu
* that allows the user to select one of 4 colors.
*
* Files: System Macros and equates
*        Menus.Inits.aii
*
* Modification History:
*
* Version 1.0       Jim Mensch
*      7/11/88      First Release
*
* Version 1.1       Jim Mensch
*      8/11/88      Fixed bug in green color selection not working              
*
*******************************************************************************


**********************************************************************
*                                                                    *
*             Apple IIGS Source Code Sampler, Volume I               *
*                                                                    *
*             Copyright (c) Apple Computer, Inc. 1988                *
*                       All Rights Reserved                          *
*                                                                    *
*            Written by Apple II Developer Tech Support              *
*                                                                    *
*                                                                    *
*                                                                    *
*  ----------------------------------------------------------------  *
*                                                                    *
*     This program and its derivatives are licensed only for         *
*     use on Apple computers.                                        *
*                                                                    *
*     Works based on this program must contain and                   *
*     conspicuously display this notice.                             *
*                                                                    *
*     This software is provided for your evaluation and to           *
*     assist you in developing software for the Apple IIGS           *
*     computer.                                                      *
*                                                                    *
*     DISCLAIMER OF WARRANTY                                         *
*                                                                    *
*     THE SOFTWARE IS PROVIDED "AS IS" WITHOUT                       *
*     WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,               *
*     WITH RESPECT TO ITS MERCHANTABILITY OR ITS FITNESS             *
*     FOR ANY PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO             *
*     THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH            *
*     YOU.  SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU (AND            *
*     NOT APPLE OR AN APPLE AUTHORIZED REPRESENTATIVE)               *
*     ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING,             *
*     REPAIR OR CORRECTION.                                          *
*                                                                    *
*     Apple does not warrant that the functions                      *
*     contained in the Software will meet your requirements          *
*     or that the operation of the Software will be                  *
*     uninterrupted or error free or that defects in the             *
*     Software will be corrected.                                    *
*                                                                    *
*     SOME STATES DO NOT ALLOW THE EXCLUSION                         *
*     OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY              *
*     NOT APPLY TO YOU.  THIS WARRANTY GIVES YOU SPECIFIC            *
*     LEGAL RIGHTS AND YOU MAY ALSO HAVE OTHER RIGHTS                *
*     WHICH VARY FROM STATE TO STATE.                                *
*                                                                    *
*                                                                    *
**********************************************************************


                    mcopy menus.macros
                    copy 2/ainclude/E16.Quickdraw
                    copy 2/ainclude/E16.Memory
                    copy 2/ainclude/E16.Event
                    copy 2/ainclude/E16.Window
                    copy 2/ainclude/E16.Dialog
                    
DPHandle           gequ 0
DPPointer          gequ DPHandle+4
DeRef              gequ DPPointer+4
LastTick           gequ 10
temp1              gequ 12
temp2              gequ 14
LinePt             gequ 16
ScreenTab          gequ 20
CustomMHandle      gequ 24
CustomMPtr         gequ 28

MarkItem           gequ 258
testINum           gequ 267
AddMenuItem        gequ 263
DelMenuItem        gequ 265
AddAMenu           gequ 264
DelAMenu           gequ 266
CMenuNums          gequ 273

ScreenMode         gequ Mode320
ScreenWidth        gequ 320
; menu record offsets

MRMenuID           gequ $00
MRMenuWidth        gequ $02
MRMenuHeight       gequ $04
MRMenuProc         gequ $06
MRMenuFlag         gequ $0A
MRMenuTWidth       gequ $0E
MRMenuTPtr         gequ $10

                    EJECT
*******************************************************************************
*
Menus               start
*
* Description:      Main code of the program. This routine calls all the other
*                   main program parts in order.
*
*
* Inputs:           None
*
* Outputs:          None
*
* External Refs:
*                   Import QuitParms
*                   Import InitTools
*                   Import InitApp
*                   Import EventLoop
*                   Import CloseTools
*
* Entry Points:
*
*******************************************************************************
                    using globals
                    jsr InitTools
                    jsr InitApp

                    _ShowCursor

                    jsr EventLoop
                    jsr CloseTools

                    _Quit QuitParms

                    end

                    EJECT
*******************************************************************************
*
Globals             data
*
* Description:      This area contains data used in all routines of the program
*                   it also contains some data structures used by Menus.Init
*
*
* Inputs:           None
*
* Outputs:          None
*
* External Refs:
*                   Export QuitParms
*                   Import CustomMenu
*
* Entry Points:
*
*******************************************************************************
*
* standard global data here
*
*******************************************************************************
TitleString         str 'Apple IIgs Menus Demo'
AutString           str 'By Jim Mensch Apple DTS'
CRString            str '(c)1988 Apple Computer'
VersString          str 'Version: 1.1'

MenuHeight          ds 2                ; Stored height of menu bar
MyID                ds 2                ; application ID
MyDP                ds 2                ; My zero page storage

QuitFlag            ds 2
QuitParms           dc i4'0'            ; Pathname of next app
                    dc i2'$00'          ; flags
EventRecord         ANOP
EventWhat           ds 2
EventMessage        ds 4
EventWhen           ds 4
EventWhere          ds 4
EventModifiers      ds 2
TaskData            ds 4
TaskMask            dc i4'$0000FFFF'

*
* Application specific data goes here
*

AppMenu             dc c'$$@\N1',h'0D'
                    dc c'--About Menus...\N256U',h'0D'
                    dc c'.'
FileMenu            dc c'$$ File \N2',h'0D'
                    dc c'--Quit\N257*Qq',h'0D'
                    dc c'.'
MenuMenu            dc c'$$ Actions \N3',h'0D'
                    dc c'--Mark Item\N258*Cc',h'0D'
                    dc c'--Set Blinks\N259',h'0D'
                    dc c'--Change test Item text\N260',h'0D'
                    dc c'--disable test item\N261',h'0D'
                    dc c'--enable test item\N262',h'0D'
                    dc c'--Add a menu item\N263',h'0D'
                    dc c'--Add a menu\N264D',h'0D'
                    dc c'--Delete a menu item\N265D',h'0D'
                    dc c'--Delete a menu\N266V',h'0D'
                    dc c'--Test Item\N267',h'0D'
                    dc c'.'

CMDTitle            dc c'$$  Custom \N5',h'0D'
                    dc c'.'
                    
TestMenu            dc c'$$  Test \N4',h'0D'
                    dc c'--Normal\N268',h'0d'
                    dc c'--Bold\N269B',h'0D'
                    dc c'--disabled\N270D',h'0d'
                    dc c'--Italics\N271I',h'0d'
                    dc c'--Color Replace Highlight\N272X',h'0d'
                    dc c'.'

Rect                ds 8
MyRect              ds 8

TestMHandle         ds 4

CMDMenuProc         dc i4'CustomMenu'   ; custom menu proc
PatTable            dc i4'MyPattern1,MyPattern2,MyPattern3,MyPattern4'

MyPattern1          dc i1'$55,$55,$55,$55' ; patterns used by                   the custom menu
                    dc i1'$55,$55,$55,$55' ; when the user selects a color
                    dc i1'$55,$55,$55,$55' ; these are the patterns that are
                    dc i1'$55,$55,$55,$55' ; used to set the menu bar color
                    dc i1'$55,$55,$55,$55'
                    dc i1'$55,$55,$55,$55'
                    dc i1'$55,$55,$55,$55'
                    dc i1'$55,$55,$55,$55'
MyPattern2          dc i1'$77,$77,$77,$77'
                    dc i1'$77,$77,$77,$77'
                    dc i1'$77,$77,$77,$77'
                    dc i1'$77,$77,$77,$77'
                    dc i1'$77,$77,$77,$77'
                    dc i1'$77,$77,$77,$77'
                    dc i1'$77,$77,$77,$77'
                    dc i1'$77,$77,$77,$77'
MyPattern3          dc i1'$44,$44,$44,$44'
                    dc i1'$44,$44,$44,$44'
                    dc i1'$44,$44,$44,$44'
                    dc i1'$44,$44,$44,$44'
                    dc i1'$44,$44,$44,$44'
                    dc i1'$44,$44,$44,$44'
                    dc i1'$44,$44,$44,$44'
                    dc i1'$44,$44,$44,$44'
MyPattern4          dc i1'$22,$22,$22,$22'
                    dc i1'$22,$22,$22,$22'
                    dc i1'$22,$22,$22,$22'
                    dc i1'$22,$22,$22,$22'
                    dc i1'$22,$22,$22,$22'
                    dc i1'$22,$22,$22,$22'
                    dc i1'$22,$22,$22,$22'
                    dc i1'$22,$22,$22,$22'
                    end


                    EJECT
*******************************************************************************
*
CustomMenu          start
*
* Description:      This is the whole custom menu routine. This routine takes care
*                   of all drawing and selecting of the custom menu. It starts out 
*                   with a dispatch routine to dispatch the operations the menu
*                   manager requests.
*
*
* Inputs:           None
*
* Outputs:          None
*
* External Refs:    None
*
* Entry Points:     None
*
*******************************************************************************
                    using Globals
local               equ 8               ; number of bytes of local stack frame
Temp                equ $01
mPtr                equ $04
RetAddr             equ $01+local       ; stack frame constants
MenuParam           equ $04+local
yHitPt              equ $06+local
xHitpt              equ $08+local
rectPtr             equ $0A+local
mHandle             equ $0E+local
menuMessage         equ $12+local
Result              equ $14+local

MaxItems            equ 5               ; number of menu items +1
CMenuWidth          equ 50              ; menu is 50 x 50 pixels
CMenuHeight         equ 50

                    tdc                 ; save the DPage
                    sta >tempDPage      ; to a temp value
                    tsc                 ; get the stack pointer
                    sta >tempStack      ; and save it...

                    sec
                    sbc #Local          ; add in our temp data storage
                    tcs                 ; set it as the stack pointer
                    tcd                 ; and as the Dpage register

                    phb                 ; save the data bank register
                    phk                 ; and switch to current bank
                    plb

                    stz Result          ; zero out result ahead of time

                    lda [mHandle]       ; dereference the menu handle
                    sta mPtr
                    ldy #2
                    lda [mHandle],y
                    sta mPtr+2

                    lda menuMessage     ; now handle the message
                    asl a
                    tax
                    jmp (CMJumpTab,x)

CMenuDone           ANOP
                    plb                 ; restore the data bank register
                    lda >tempDPage      ; restore Dpage
                    tcd
                    lda >TempStack      ; restore stack pointer
                    tcs
                    ShortM              ; now discard parameter list
                    pla                 ; save the return address in a and X
                    plx

                    ply                 ; discard all the parameters
                    ply
                    ply
                    ply
                    ply
                    ply
                    ply
                    ply

                    phx                 ; restore the return addres previously saved
                    pha
                    LongM

                    rtl

*
*   CMGetID -   accepts a menu internal ID number and converts it into an
*               application menu ID number. This is the number that is given
*               to the application by taskmaster when you have completed
*               your menu selection.
*

CMGetID             ANOP
                    lda menuparam       ; get the internal item ID
                    clc                 ; and add application offset to
                    adc #CMenuNums      ; create actual item number
                    sta result          ; save the result
                    brl CMenuDone       ; and return back to dispatch routine

*
*   CMDrawI -   Called when the menu manager wants to Hilight/unhilight a
*               menu item in your menu ( when mouse is dragged onto or off
*               of the item ) This routine calls either DrawItem or HilighItem
*               depending on the request
*

CMDrawI             ANOP
                    lda menuParam       ; get the number
                    bmi CMDIHiLite      ; if high bit set then highlite
                    jsr DrawItem        ; else just draw it
                    brl CMenuDone
CMDIHiLite          and #$7FFF          ; strip the high bit
                    jsr InvertItem
                    brl CMenuDone

*
*   CMDrawT -   The menu manager asks for this call when it is drawing the
*               menu title. I want the menu manager to draw my title
*               so I just pass back a false result and the menu mgr handles
*               it for me

CMDrawT             ANOP
                    stz Result          ; false to have menu mgr do this...
                    brl CMenuDone

*
*   CMSize -    Calculate values for menuWidth and menuHeight in the menu record
*

CMSize              ANOP
                    ldy #MRmenuWidth    ; offset into menu record
                    lda [mPtr],y        ; get the width parameter
                    bne CMS0010         ; if non-zero do not change the value           
                    lda #CMenuWidth     ; save # of pixels wide
                    sta [mPtr],y
CMS0010             ldy #MRmenuHeight   ; offset into menu record for height
                    lda [mPtr],y        ; load the height
                    bne CMS0020         ; if non-zero do not change them
                    lda #CMenuHeight
                    sta [mPtr],y
CMS0020             ANOP
                    brl CMenuDone

*
*   CMChoose -  Routine called when user mouse location changes. This routine
*               should return  in the result the internal ID number of the
*               item the mouse point is currently over. If no item selected
*               leave the result alone.
*

CMChoose            ANOP
                    lda #1              ; initialize the counter at 1
                    sta ItemTemp        ; This will count thru each menu item to test
CMC0010             ANOP
                    lda ItemTemp        ; get the item number to test
                    cmp #MaxItems       ; are we done yet???
                    bge CMCDone         ; if so then quit...
                    jsr testHit         ; test each item for a hit
                    bne CMCHit          ; if non-zero got a hit
                    inc ItemTemp        ; bump the counter
                    bra CMC0010         ; and try the next item
CMCHit              lda ItemTemp        ; got a hit so return the number
                    ora #$8000          ; set high order bit to flag as selected
                    sta result          ; and save it as the result
CMCDone             ANOP
                    brl CMenuDone       ; and leave

*
*   CMDraw -    This routine draws the contents of the custom menu when the
*               menu is first selected.
*

CMDraw              ANOP

                    lda #1              ; draw item 1
                    jsr DrawItem

                    lda #2
                    jsr DrawItem

                    lda #3
                    jsr DrawItem

                    lda #4
                    jsr DrawItem

                    brl CMenuDone

*
* SetUpRect - sets TempRect equal to the rectangle of the custom menu item
* in <A>. This routine is used by drawItem,InvertItem and TestHit
*

SetUpRect           ANOP
                    dec a               ; item numbers based off of 1 not 0
                    asl a               ; item number *8 for offset into rect table
                    asl a
                    asl a
                    tax                 ; place it in x to use as an index

                    ldy #2              ; get values to offset rectangle by
                    lda [RectPtr],y     ; wmgr rectangle left
                    sta tempPt+2        ; and save it for use later
                    lda [RectPtr]       ; now get the top
                    sta tempPt

                    lda MyRect1,x       ; load in the top
                    clc                 ; and add the offset
                    adc tempPt
                    sta tempRect        ; and store it 

                    lda MyRect1+2,x     ; load in the left
                    clc
                    adc tempPt+2        ; offset it
                    sta tempRect+2

                    lda MyRect1+4,x     ; Load the bottom
                    clc
                    adc tempPt
                    sta tempRect+4

                    lda MyRect1+6,x     ; and finally the right
                    clc
                    adc tempPt+2
                    sta tempRect+6

                    rts

*
*   DrawItem -  Draw the menu item contained in A
*

DrawItem            ANOP                ; draws item specified by a
                    sta itemTemp
                    jsr SetUpRect

                    PushLong #TempRect
                    lda PatTable+2      ; get high word of pattern addr
                    pha
                    lda itemTemp        ; push pattern ptr low byte
                    dec a               ; item# based from 1 not 0
                    asl a               ; multiply by 4 and use it as a
                    asl a               ; table offset
                    tax
                    lda PatTable,x
                    pha
                    _FillRect
                    rts

*
*   InvertItem -    Invert an Item to show it is selected
*

InvertItem          ANOP
                    jsr SetUpRect

                    PushLong #TempRect
                    _InvertRect
                    rts

*
*   TestHit -   With an Item number passed in A test to see if 
*               the cursor is over the Item. If so return true, if not return false
*

TestHit             ANOP
                    jsr SetUpRect       ; create rectangle to test

                    lda yHitPt          ; create a point from the passed data
                    sta tempPt          ; since we must pass this data by pointer
                    lda xHitPt          ; to PtInRect, we must move the data from
                    sta tempPt+2        ; the stack frame into temp storage

                    PushWord #0         ; room for result
                    PushLong #TempPt    ; current cursor location
                    PushLong #TempRect  ; item rectangle to test
                    _PtInRect
                    pla                 ; return result in A

                    rts

*
*   Data storage area for the custom menu routine
*

tempStack           ds 2                ; storage for Stack and Dpage registers
tempDPage           ds 2
CMJumpTab           ANOP                ; jump table for the dispatch routine
                    dc i2'CMDraw'       ; mDrawMenu routine
                    dc i2'CMChoose'     ; mChoose routine
                    dc i2'CMSize'       ; mSize routine
                    dc i2'CMDrawT'      ; mDrawTitle routine
                    dc i2'CMDrawI'      ; mDrawMItem Routine
                    dc i2'CMGetID'      ; mGetMItemID routine

MyRect1             dc i2'3,3,23,23'    ; rectangles for the 4 menu items
MyRect2             dc i2'25,3,45,23'
MyRect3             dc i2'3,25,23,45'
MyRect4             dc i2'25,25,45,45'
TempRect            ds 8                ; temp rectangle to use in various places
TempPt              ds 4                ; temp point to use in various places
ItemTemp            ds 2

                    end

                    EJECT
*******************************************************************************
*
InitApp             start
*
* Description:      Initialize my menu bar and the quit flags. This demonstrates how
*                   to install a custom menu!
*
*
* Inputs:           None
*
* Outputs:          None
*
* External Refs:
*
* Entry Points:
*
*******************************************************************************
                    using Globals

                    Stz QuitFlag        ; initialize the quit flag


                    PushLong #0         ; room for result
                    PushLong #CMDTitle  ; our custom menu
                    _NewMenu            ; now create a new menu

                    lda 1,s             ; get menu pointer for later use
                    sta CustomMHandle   ; while leaving them on the stack   
                    lda 3,s
                    sta CustomMHandle+2

                    lda [CustomMHandle] ; dereference the menu handle 
                    sta CustomMPtr
                    ldy #2
                    lda [CustomMHandle],y
                    sta CustomMPtr+2

                    lda CMDMenuProc     ; now fix it so that this is a cust menu
                    ldy #MRMenuProc     ; by setting the menu proc to point to 
                    sta [CustomMPtr],y  ; our custom procedure

                    lda CMDMenuProc+2
                    iny
                    iny
                    sta [CustomMPtr],y

; Set up custom menu info here ....

                    PushWord #0         ; menu handle already on stack insert 
                    _InsertMenu         ; it before all other menus

                    PushLong #0
                    PushLong #TestMenu
                    _NewMenu

                    lda 1,s             ; get menu pointer for later use
                    sta TestMHandle     ; and leave it on the stack
                    lda 3,s
                    sta TestMHandle+2

                    PushWord #0
                    _InsertMenu

                    PushLong #0
                    PushLong #MenuMenu
                    _NewMenu
                    PushWord #0
                    _InsertMenu

                    PushLong #0
                    PushLong #FileMenu
                    _NewMenu
                    PushWord #0
                    _InsertMenu

                    PushLong #0
                    PushLong #AppMenu
                    _NewMenu
                    PushWord #0
                    _InsertMenu

                    PushWord #0
                    _FixMenuBar
                    Pla
                    sta MenuHeight

                    PushWord #$00F5     ; white-blue/red not selected colors
                    PushWord #$0010     ; blue/red-black selected colors
                    PushWord #$00E0     ; yellowgreen outline
                    _SetBarColors       ; now set the bar colors

                    _DrawMenuBar

                    rts
                    end

                    EJECT
*******************************************************************************
*
EventLoop           start
*
* Description:      The event loop recieves events and dispatches them. When
*                   the quitflag is non-zero, it exits.
*
* Inputs:           None
*
* Outputs:          None
*
* External Refs:
*                   Import MenuSelect
*                   Import Ignore
*
* Entry Points:
*
*******************************************************************************
                    using Globals

                    PushWord #0         ; room for result
                    PushWord #EveryEvent ; handle all events
                    PushLong #EventRecord ; place event data here
                    _TaskMaster

                    pla                 ; get the event type here
                    beq EventLoop       ; remove if you want to use null events
                    asl A               ; multiply by two
                    tax                 ; and do a table dispatch just like menu select
                    jsr (TaskTable,x)

                    lda QuitFlag        ; test to see if user selected quit
                    beq EventLoop       ; if not just go get another event

                    rts                 ; if so, then end the event loop

TaskTable           dc i2'Ignore'       ; 0 Null
                    dc i2'Ignore'       ; 1 MouseDown
                    dc i2'Ignore'       ; 2 Mouse Up
                    dc i2'Ignore'       ; 3 KeyDown
                    dc i2'Ignore'       ; 4 Undefined
                    dc i2'Ignore'       ; 5 AutoKey
                    dc i2'Ignore'       ; 6 Update
                    dc i2'Ignore'       ; 7 undefined
                    dc i2'Ignore'       ; 8 activate
                    dc i2'Ignore'       ; 9 Switch
                    dc i2'Ignore'       ; 10 desk acc
                    dc i2'Ignore'       ; 11 device driver
                    dc i2'Ignore'       ; 12 ap
                    dc i2'Ignore'       ; 13 ap
                    dc i2'Ignore'       ; 14 ap
                    dc i2'Ignore'       ; 15 ap
                    dc i2'Ignore'       ; TASK 0 indesk
                    dc i2'MenuSelect'   ; TASK 1 in menuBar
                    dc i2'Ignore'       ; TASK 2 in system window
                    dc i2'Ignore'       ; TASK 3 in content
                    dc i2'Ignore'       ; TASK 4 in Drag
                    dc i2'Ignore'       ; TASK 5 in grow
                    dc i2'Ignore'       ; TASK 6 in goaway
                    dc i2'Ignore'       ; TASK 7 in zoom
                    dc i2'Ignore'       ; TASK 8 in info bar
                    dc i2'Ignore'       ; TASK 9 in special menu
                    dc i2'Ignore'       ; TASK 10 in NDA
                    dc i2'Ignore'       ; TASK 11 in frame
                    dc i2'Ignore'       ; TASK 12 in drop
                    end

                    EJECT
*******************************************************************************
*
MenuSelect          start
*
* Description:      This routine is called when taskmaster returns 
*                   a menu event. This routine takes the menu item that
*                   was hit and calculates an offset into the menu
*                   dispatch table. It then calls that routine
*
*
* Inputs:           None
*
* Outputs:          None
*
* External Refs:
*                   Import DoAbout
*                   Import DoQuit
*                   Import SetMark
*                   Import SetBlink
*                   Import SetName
*                   Import DisableIt
*                   Import EnableIt
*                   Import DoAdd
*                   Import DoAddM
*                   Import DoRemove
*                   Import DoRemoveM
*                   Import ColorSel
*                   Import Ignore
*
* Entry Points:
*
*******************************************************************************
                    using Globals

                    lda TaskData        ; get the menu number hit
                    sec                 ; subtract 250 ( that is where our menu numbers
                    sbc #256            ; start)
                    asl a               ; multiply it by 2 ( table has 2 byte entries )
                    tax                 ; use as an index
                    jsr (menuTable,x)   ; and jump to the routine to handle that item

                    PushWord #0         ; unhilight the menu bar now
                    PushWord taskData+2 ; menu number that was hit
                    _HiLiteMenu

                    rts
;
; the menu table should contain one entry for each menu item
;
MenuTable           dc i2'DoAbout'      ; 256 About Menus
                    dc i2'DoQuit'       ; 257 Quit
                    dc i2'SetMark'      ; 258 Mark test item
                    dc i2'SetBlink'     ; 259 Set Blink rate
                    dc i2'SetName'      ; 260 Change test item text
                    dc i2'DisableIt'    ; 261 Disable test item
                    dc i2'EnableIt'     ; 262 enable test item
                    dc i2'DoAdd'        ; 263 add menu item
                    dc i2'DoAddM'       ; 264 add menu
                    dc i2'DoRemove'     ; 265 delete menu item
                    dc i2'DoRemoveM'    ; 266 delete menu
                    dc i2'Ignore'       ; 267 test item
                    dc i2'Ignore'       ; 268 normal
                    dc i2'Ignore'       ; 269 bold
                    dc i2'Ignore'       ; 270 disabled
                    dc i2'Ignore'       ; 271 italics
                    dc i2'Ignore'       ; 272 color replace
                    dc i2'Ignore'       ; 273 Not implemented
                    dc i2'ColorSel'     ; 274 color selection
                    dc i2'ColorSel'     ; 275 color selection
                    dc i2'ColorSel'     ; 276 color selection
                    dc i2'ColorSel'     ; 277 Color selection

                    end

                    EJECT
*******************************************************************************
*
SetMark             start
*
* Description:      Demonstrate how to Mark/UnMark an item.
*
*
* Inputs:           None
*
* Outputs:          None
*
* External Refs:
*
* Entry Points:
*
*******************************************************************************

                    PushWord #0         ; room for result
                    PushWord #MarkItem  ; test menu item number
                    _GetMItemMark

                    pla                 ; get current mark status
                    bne SMUnMark        ; if not zero then unmark it

                    PushWord #18        ; else mark with ascii 18
                    PushWord #MarkItem
                    _SetMItemMark
                    rts

SMUnMark            ANOP
                    PushWord #0         ; Unmark the test item
                    PushWord #MarkItem
                    _SetMItemMark
                    rts
                    end

                    EJECT
*******************************************************************************
*
EnableIt            start
*
* Description:      Demonstrate how to enable a menu item
*
*
* Inputs:           None
*
* Outputs:          None
*
* External Refs:    None
*
* Entry Points:
*
*******************************************************************************

                    PushWord #testINum
                    _EnableMItem
                    rts
                    end


*******************************************************************************
*
DisableIt           start
*
* Description:      Demonstrate how to disable a menu item
*
*
* Inputs:           None
*
* Outputs:          None
*
* External Refs:    None
*
* Entry Points:     None
*
*******************************************************************************
                    PushWord #testINum
                    _DisableMItem
                    rts
                    end

                    EJECT
*******************************************************************************
*
SetName             start
*
* Description:      Change the name of the test item. This routine will
*                   toggle between the names 'Test Item' and 'Improved Test Item'
*                   to show how to change an Item name.
*
* Inputs:           None
*
* Outputs:          None
*
* External Refs:
*
* Entry Points:
*
*******************************************************************************
                    lda NameFlag        ; test state of current name if non then
                    beq SN0010          ; name still original/ needs changing

                    stz NameFlag        ; zero name flag to denote alt name
                    PushLong #NewName   ; Set the new name
                    PushWord #testINum
                    _SetMItemName
                    rts
SN0010              ANOP
                    lda #1              ; set flag to denote original item displayed
                    sta NameFlag
                    PushLong #OrigName
                    PushWord #testINum
                    _SetMItemName
                    rts
NewName             str 'Improved test item'
OrigName            str 'Test Item'
NameFlag            dc i2'1'
                    end

                    EJECT
*******************************************************************************
*
SetBlink            start
*
* Description:      Changes the number of times selected menu items blink.
*
*
* Inputs:           None
*
* Outputs:          None
*
* External Refs:
*
* Entry Points:
*
*******************************************************************************
                    PushWord BRate
                    _SetMItemBlink

                    lda BRate
                    eor #$0003          ; xor with 3 to swap between 1 and 2
                    sta BRate

                    rts
BRate               dc i2'1'            ; the next blink rate
                    end

                    EJECT
*******************************************************************************
*
ColorSel            start
*
* Description:      This routine will be called when the user selects one of 
*                   the custom menu items. It will change the menu bar color
*                   to the color selected by the user.
*
*
* Inputs:           TaskData - Menu item selected
*
* Outputs:          None
*
* External Refs:    None
*
* Entry Points:     None
*
*******************************************************************************
                    using Globals

                    lda taskData        ; get the menu number
                    sec                 ; and make it a number between 0 and 3
                    sbc #CMenuNums+1    ; by subtracting the selection offset
                    asl a               ; multiply by 4 to use as a table offset
                    asl a
                    tax
                    lda PatTable,x      ; get address of pattern
                    sta deref           ; and use it as a pointer
                    lda (deref)         ; get the selected color
                    and #$000F          ; strip off high bytes
                    ora #$00F0          ; set nibble to white
                    pha                 ; set menu colors to white/selected color

                    PushWord #$0040     ; blue/black selected colors
                    PushWord #$0020     ; brown outline
                    _SetBarColors

                    _DrawMenuBar

                    rts
                    end
                    
                    EJECT
*******************************************************************************
*
Ignore              start
*
* Description:      This routine is called for all events and menu selection
*                   that are not handled by this program. Like the name says
*                   it ignores them.
*
*
* Inputs:           None
*
* Outputs:          None
*
* External Refs:
*
* Entry Points:
*
*******************************************************************************
                    rts
                    end


*******************************************************************************
*
DoQuit              start
*
* Description:      This routine stores a non-zero value in the quit flag to
*                   notify the event loop that the user wants to stop the
*                   program.
*
*
* Inputs:           None
*
* Outputs:          None
*
* External Refs:
*
* Entry Points:
*
*******************************************************************************
                    using Globals

                    lda #1
                    sta QuitFlag
                    rts
                    end

                    EJECT
*******************************************************************************
*
DoAdd               start
*
* Description:      Demonstrates hot to Add an Item to an existing menu. 
*                   After adding the item this routine disables 
*                   the Add item and enable the delete item.
*
*
* Inputs:           None
*
* Outputs:          None
*
* External Refs:
*
* Entry Points:
*
*******************************************************************************
                    using Globals

                    PushLong #NewItem   ; Pointer to the new Item
                    PushWord #$FFFF     ; Insert at end of the menu
                    PushWord #$03       ; insert into menu 3
                    _InsertMItem

                    PushWord #0         ; Call calc Menusize to get menu mgr to
                    PushWord #0         ; recalc the menu size. 
                    PushWord #3         ; Use zeros for auto calculation
                    _CalcMenuSize

                    PushWord #AddMenuItem ; Now disable the Add item 
                    _DisableMItem

                    PushWord #DelMenuItem ; and enable the delete item so the 
                    _EnableMItem        ; user can get rid of item just added

                    rts
NewItem             dc c'--New Item\N318D',h'0D' 
                    end

                    EJECT
*******************************************************************************
*
DoRemove            start
*
* Description:      Demonstrate how to remove an item. The menu item
*                   for this routine is enabled only after AddItem adds
*                   an item. This routine disables the delete item and
*                   re-enables the add item
*
*
* Inputs:           None
*
* Outputs:          None
*
* External Refs:
*
* Entry Points:
*
*******************************************************************************
                    using Globals

                    PushWord #318       ; item ID of added item
                    _DeleteMItem

                    PushWord #0         ; recalc menu size with automatic 
                    PushWord #0         ; calculation by passing 0's
                    PushWord #3         ; recalc menu 0
                    _CalcMenuSize

                    PushWord #DelMenuItem ; disable this cause now, theres 
                    _DisableMItem       ; nothing to remove

                    PushWord #AddMenuItem ; enable this again, so the user 
                    _EnableMItem        ; can try again

                    rts
                    end

                    EJECT
*******************************************************************************
*
DoRemoveM           start
*
* Description:      Demonstrate how to remove an entire menu from the menu bar
*
*
* Inputs:           None
*
* Outputs:          None
*
* External Refs:
*
* Entry Points:
*
*******************************************************************************
                    using Globals

                    PushWord #4         ; menu number to remove
                    _DeleteMenu

                    _DrawMenuBar        ; redraw the menu bar

                    PushWord #DelAMenu  ; disable this feature and enable Addmenu
                    _DisableMItem

                    PushWord #AddAMenu
                    _EnableMItem

                    rts
                    end

                    EJECT
*******************************************************************************
*
DoAddM              start
*
* Description:      Demonstrate how to add a menu to the menu bar.
*
*
* Inputs:           None
*
* Outputs:          None
*
* External Refs:
*
* Entry Points:
*
*******************************************************************************
                    using Globals

                    PushLong TestMHandle ; handle to the test menu we saved in InitApp
                    PushWord #3         ; insert after menu 3
                    _InsertMenu

                    _DrawMenuBar        ; redraw the menu bar

                    PushWord #AddAMenu  ; and disable this menu option
                    _DisableMItem

                    PushWord #DelAMenu  ; enable the option to delete this menu
                    _EnableMItem

                    rts
                    end
                    
                    copy Menus.inits.aii

                    END
